package com.bigdata.security.shiro.filter;/**
 * Created by Administrator on 2019/7/17 0017.
 */

import com.bigdata.common.em.CommonEnum;
import com.bigdata.model.User;
import com.bigdata.mysql.entity.JkfwUser;
import com.bigdata.service.mysql.JkfwUserService;
import com.bigdata.security.jwt.JwtUtil;
import com.bigdata.security.shiro.token.OAuth2Token;
import com.bigdata.utils.ResponseUtil;
import com.bigdata.utils.ServletUtils;
import com.bigdata.utils.shiro.ShiroUtils;
import com.bigdata.model.AjaxResult;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * @author Administrator
 * @description
 * @date 2019/7/17 0017
 **/
public class OAuth2Filter extends AuthenticatingFilter {
    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    JkfwUserService jkfwUserService;

    @Override
    protected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        String token = getRequestToken((HttpServletRequest) servletRequest);
        if (StringUtils.isNoneBlank(token)) {
            return null;
        }
        return new OAuth2Token(token);
    }


    private String getRequestToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        if (StringUtils.isEmpty(token)) {
            Cookie[] cookies = request.getCookies();
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("token")) {
                    token = cookie.getValue();
                }
            }
        }
        return token;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        return super.isAccessAllowed(request, response, mappedValue);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        if (ShiroUtils.getSubject().isAuthenticated()) {
            return true;
        }
        String token = getRequestToken((HttpServletRequest) servletRequest);
        if (StringUtils.isEmpty(token)) {//没有token
            if (ServletUtils.isAjaxRequest((HttpServletRequest) servletRequest)) {
                HttpServletResponse response = (HttpServletResponse) servletResponse;
                AjaxResult result = new AjaxResult();
                result.setCode(AjaxResult.CODE_NOTLOGIN);
                result.setMessage(URLEncoder.encode("您还没有登录！", "UTF-8"));
                Gson gson = new Gson();
                String res = gson.toJson(result);
                ResponseUtil.renderJson(response, res);
                return false;
            } else {
                return executeLogin(servletRequest, servletResponse);
            }
        } else {
            String username = jwtUtil.getUsernameFromToken(token);
            JkfwUser jkfwUser = jkfwUserService.queryUserLogin(username);
            if (jkfwUser.getStatus() == CommonEnum.UserStatus.ok.getIdx()) {
                User u = new User(jkfwUser);
                if (jwtUtil.validateToken(token, u)) {
                    return true;
                } else {
                    HttpServletResponse response = (HttpServletResponse) servletResponse;
                    AjaxResult result = new AjaxResult();
                    result.setCode(AjaxResult.CODE_NOTLOGIN);
                    result.setMessage(URLEncoder.encode("用户认证失败，请重新认证！", "UTF-8"));
                    Gson gson = new Gson();
                    String res = gson.toJson(result);
                    ResponseUtil.renderJson(response, res);
                    return false;
                }
            } else {
                HttpServletResponse response = (HttpServletResponse) servletResponse;
                AjaxResult result = new AjaxResult();
                result.setCode(AjaxResult.CODE_NOTLOGIN);
                result.setMessage(URLEncoder.encode("该用户不存在！", "UTF-8"));
                Gson gson = new Gson();
                String res = gson.toJson(result);
                ResponseUtil.renderJson(response, res);
                return false;
            }
        }
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        if (ServletUtils.isAjaxRequest((HttpServletRequest) request)) {
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            Throwable throwable = e.getCause() == null ? e : e.getCause();
            AjaxResult result = new AjaxResult();
            result.setCode(AjaxResult.CODE_NOTLOGIN);
            result.setMessage(throwable.getMessage());
            Gson gson = new Gson();
            String res = gson.toJson(result);
            ResponseUtil.renderJson(httpServletResponse, res);
            return false;
        }
        try {
            redirectToLogin(request, response);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return false;
    }

    @Override
    protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
        super.issueSuccessRedirect(request, response);
    }

}
